/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
 *
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
 * Other names may be trademarks of their respective owners.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 *
 * Contributor(s):
 *
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
 */
package org.nico.db.sql.editor.completion;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.logging.Logger;
import javax.swing.Action;
import org.netbeans.spi.editor.completion.CompletionDocumentation;
import org.nico.db.sql.editor.PostgisFunction;
import org.nico.db.sql.editor.PostgisMetadata;
import org.openide.util.NbBundle;

/**
 *
 * @author nicolas ribot
 */
public class PostgisCompletionDocumentation implements CompletionDocumentation {

    private static final Logger LOGGER = Logger.getLogger(PostgisCompletionDocumentation.class.getName());
    // TODO: config to set the postgis site
    // TODO: XML parser to read XML doc from sources
    private SQLCompletionItem.Procedure item;
    private Map<String, List<PostgisFunction>> docNames = new HashMap<String, List<PostgisFunction>>();
    /**
     * the postgis doc link to resolve
     */
    private String linkToResolve;

    public PostgisCompletionDocumentation() {
        this.docNames = PostgisMetadata.getInstance().getPgObj().getFunctionsDocMap();
    }

    public PostgisCompletionDocumentation(SQLCompletionItem.Procedure item) {
        this();
        this.item = item;
    }

    /**
     * Ctor for resolveLink function
     */
    public PostgisCompletionDocumentation(String htmlLink) {
        this();
        this.linkToResolve = htmlLink;
    }

    /**
     * Returns the documentation URL for this resource, according to the current
     * object state, that can be called with a Procedure object or just a String
     * in case of resolveLink action.
     * 
     */
    private String getDocUrl() {
        String res = "";

        String version = PostgisMetadata.getInstance().getPgObj().version;
        if (this.item != null) {
            res = PostgisMetadata.DOC_URL.replace("PROC_NAME", this.getProcDocName()).replace("VERSION", version);//NOI18N
        } else {
            res = PostgisMetadata.DOC_URL.replace("PROC_NAME.html", this.linkToResolve).replace("VERSION", version);//NOI18N
        }
        return res;
    }

    /**
     * Returns the name of the Postgis function (Procedure item) as generated in
     * the HTML doc, or the original function name if not found
     * 
     * TODO: if function name not found: error message or postgis home page ?
     * error is more db-independant
     *
     * TODO: clean code !
     * @return
     */
    private String getProcDocName() {
        //String res = "index";//NOI18N
        String res = "";//NOI18N
//        if (this.docNames != null && item != null && item.getName() != null
//                && this.docNames.containsKey(item.getName().toLowerCase())) {
//            // no indentation to let i18n.pl to read this sentence properly...
//            LOGGER.info(NbBundle.getMessage(PostgisCompletionDocumentation.class, "PostgisCompletionDocumentation.MSG.GettingMapNameForItem", item.getName()));
//            // keys are lowercase in the map. The first function found in the list is enough to get its name 
//            String s = this.docNames.get(item.getName().toLowerCase()).get(0).getName();
//            if (s != null) {
//                res = s;
//            }
//        }  else {
//            res = item.getName();
//        }
        if (item != null) {
            res = item.getPostgisProcedure().getHtmlDoc();
        }
        return res;
    }

    @Override
    public String getText() {
        String res = null;

        try {
            URL u = new URL(this.getDocUrl());
            res = new Scanner(u.openStream(), "ISO-8859-1").useDelimiter("\\A").next(); //NOI18N
        } catch (IOException ex) {
            // no indentation to let i18n.pl to read this sentence properly...
            res = NbBundle.getMessage(PostgisCompletionDocumentation.class, "PostgisCompletionDocumentation.HTML.NoDocumentation", (item == null ? this.linkToResolve : this.item.getName()));
            //res = NbBundle.getMessage(PostgisCompletionDocumentation.class, "PostgisCompletionDocumentation.HTML.NoPostgisSite", this.getDocUrl(), (item == null ? this.linkToResolve : this.item.getName()), ex.toString());
            //res = "";
        }
        return res;
    }

    @Override
    public URL getURL() {
        URL res = null;
        try {
            res = new URL(this.getDocUrl());
        } catch (MalformedURLException murle) {
            //LOGGER.severe("Invalid postgis doc URL: " + murle.toString());
        }
        return res;
    }

    @Override
    public CompletionDocumentation resolveLink(String string) {
        //LOGGER.info("resolveLink: " + string);
        return new PostgisCompletionDocumentation(string);
    }

    @Override
    public Action getGotoSourceAction() {
        return null;
    }
}
